package sy5_Structural_Pattern.decorator.decorator2;
/*
 * 装饰者模式示例：食品、饮料订单计价程序。
 */

import lombok.Data;

@Data
abstract class Order{  //订单作为抽象构件

	private String des; //订单描述
	private float price; //单价

	public abstract float  cost(); //抽象方法：计算费用

}

class Coffee extends Order{   //具体构件类的子类，表示被装饰对象
	public Coffee() {
		setPrice(5.0f);
		setDes("咖啡");
	}

	@Override
	public float cost() {  //实现抽象方法
		return 5.0f;
	}
}

abstract class Decorator extends Order{  //装饰基类

	private Order order;  //聚合

	public  Decorator(Order order) {  //构造器注入
		this.order=order;
	}

	public Order getOrder() {
		return order;
	}

	public String getDes() {
		return super.getDes()+"  "+super.getPrice()+" && "+order.getDes();
	}

	/*@Override
	//如果重写下面的抽象方法，则本类不必设计为抽象类。同时，可以去掉本类的getter方法和装饰子类里重写的cost()方法。
	public float cost() {
		return super.getPrice()+order.cost();  //迭加
	}*/
}

class Chocolate extends Decorator{  //具体装饰类

	public Chocolate(Order order) {
		super(order);
		setDes("巧克力");
		setPrice(3.0f);
	}

	@Override
	public float cost() {
		return super.getPrice()+super.getOrder().cost();
	}
}

class Milk extends Decorator{  //具体装饰类

	public Milk(Order order) {
		super(order);
		setDes("牛奶");
		setPrice(2.0f);
	}

	@Override
	public float cost(){
		return super.getPrice()+super.getOrder().cost();
	}
}

public class Client{ //客户端
	public static void main(String[] args) {
		//step1
		Order order = new Coffee();  //初始订单，被装饰类
		System.out.println("描述："+order.getDes());
		System.out.println("费用："+order.cost());
		//System.out.println("费用："+order.getPrice());
		System.out.println("=========");

		//step2
		order = new Milk(order);  //订单迭加，装饰
		System.out.println("order加一份牛奶后的费用："+order.cost());
		System.out.println("描述="+order.getDes());
		System.out.println("============================");

		//step3
		order = new Chocolate(order);  //订单迭加，继续装饰
		System.out.println("order再加一份巧克力后的费用："+order.cost());
		System.out.println("描述="+order.getDes());





		System.out.println("===============================================");

		//step4
		order = new Chocolate(order);  //订单迭加，继续装饰
		System.out.println("order再加一份巧克力后的费用："+order.cost());
		System.out.println("描述="+order.getDes());

	}
}
